#pragma once
#include <iostream>
#include <vector>
#include<semaphore.h>
using namespace std;

const int defaultsize = 5;

template <class T>
class Ringqueue
{
    void P(sem_t& sem)
    {
        sem_wait(&sem);
    }
    void V(sem_t& sem)
    {
        sem_post(&sem);
    }
    public:
    Ringqueue(int size = defaultsize) : _size(size), _ringqueue(size),_p_step(0)
     ,_c_step(0)
    {
        sem_init(&_space_sem,0,size);//szie是指最开始空间资源为size
        sem_init(&_data_sem,0,0);//0是指最开始数据资源为0
    }
    void Push(const T& in)
    {
        //生产
        P(_space_sem);//对空间资源进行减操作，如果_space_sem已经为0，将被阻塞在这里
        _ringqueue[_p_step]=in;//将数据资源放到队列中

        _p_step++;//生产者向前走
        _p_step%=_size;//控制为环形队列
        V(_data_sem);//增加数据资源的值
    }

    void Pop(T* out)
    {
        //消费
        P(_data_sem);//对数据资源进行减操作，如果_space_sem已经为0，将被阻塞在这里
        *out=_ringqueue[_c_step];//将数据资源取出
        _c_step++;//生产者向前走
        _c_step%=_size;//控制为环形队列
        V(_space_sem);//增加空间资源的值
    }

    ~Ringqueue()
    {
        sem_destroy(&_space_sem);
        sem_destroy(&_data_sem);
    }

private:
    vector<T> _ringqueue;
    int _size; // 环形队列的大小

    int _p_step;//生产者在队列的位置
    int _c_step;//消费者在队列的位置

    sem_t _space_sem;//空间信号量，生产者关心
    sem_t _data_sem;//数据信号量，消费者关心
};
